﻿#include "interpretor.h"

using namespace std;

//在与程序同目录下创建sudoku.txt
int createSudokuTxt()
{
	WCHAR exe_path[MAX_PATH];
	GetModuleFileName(NULL, exe_path, MAX_PATH);
	for (int i = lstrlenW(exe_path); i >= 0; i--)
	{
		if (exe_path[i] == L'\\')
		{
			exe_path[i + 1] = 0;
			lstrcat(exe_path, L"sudoku.txt");
			break;
		}
	}
	h_sudoku_txt = CreateFile(
		exe_path,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		CREATE_ALWAYS,//已存在文件则覆盖
		FILE_ATTRIBUTE_NORMAL,
		NULL
	);
	if (h_sudoku_txt == INVALID_HANDLE_VALUE)
	{
		wcout << L"Failed to create sudoku.txt." << endl;
		return -6;
	}
	return 0;
}



//对可能是生成数独的命令进行解析
int interpretMakingSudoku(wchar_t* argv2)
{
	if (lstrlenW(argv2) > 7)//最大值1e6长度为7
	{
		cout << "Wrong Arguments." << endl;
		return -2;
	}
	for (int i = 0; i < 7 && i < lstrlen(argv2); i++)
	{
		if (argv2[i] < '0' || argv2[i] > '9')//不允许含有非数字字符
		{
			cout << "Wrong Arguments." << endl;
			return -2;
		}
	}

	//计算argv[2]并保证1<=num<=1e6
	int num = 0;
	for (int i = 0; i < lstrlenW(argv2) && num < 1000001; i++)
	{
		num *= 10;
		num += argv2[i] - '0';
	}
	if (num <= 0 || num > 1000000)
	{
		wcout << L"The number of sudoku should between 1 and1E6" << endl;
		return -3;
	}

	upper_limit_of_sudoku = num;
	int err = createSudokuTxt();
	if (err < 0) return err;
	makeSudoku();
	return 0;
}

//对可能是求解数独的命令进行解析
int interpretSolvingSudoku(wchar_t* argv2)
{
	h_sudoku_problem_txt = ::CreateFile(
		argv2,
		GENERIC_READ,
		0,
		NULL,
		OPEN_EXISTING,//文件存在才打开
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (h_sudoku_problem_txt == INVALID_HANDLE_VALUE)
	{
		wcout << L"Cannot open " << argv2 << endl;
		return -5;
	}
	int err = createSudokuTxt();
	if (err < 0) return err;
	solveSudokuProblem();
	return 0;
}

//解析命令
int interpret(int argc, wchar_t* argv[])
{
	if (argc > 3)
	{
		cout << "Too more arguments." << endl;
		return -1;
	}
	else if (argc < 3)
	{
		cout << "Too less arguments." << endl;
		return -1;
	}
	else
	{
		if (lstrcmpW(argv[1], L"-c") == 0)//可能是生成数独命令
		{
			int con = interpretMakingSudoku(argv[2]);
			closeTxt();
			return con;
		}
		else if (lstrcmpW(argv[1], L"-s") == 0)//可能是求解数独命令
		{
			int con = interpretSolvingSudoku(argv[2]);
			closeTxt();
			return con;
		}
		else
		{
			cout << "Wrong Arguments." << endl;
			closeTxt();
			return -2;
		}
	}
}
